// Copyright(c) 2008 Tri Tech Information Systems Inc. 
// Distributed under the Boost Software License, Version 1.0.
//     (See accompanying file ../../LICENSE_1_0.txt or copy at
//           http://www.boost.org/LICENSE_1_0.txt)
//     
#include <llvm/AbstractTypeUser.h>
#include <boost/python.hpp>
#include <pyxx/pointer.h>
#include <boost/shared_ptr.hpp>
#include <llvm/BasicBlock.h>
#include <iostream>

void BasicBlockDispose(llvm::BasicBlock * bb)
{

    std::cerr << bb << std::endl;
    // if python loses it
    // we should delete it iff it has no parent
    if( !bb->getParent() )
        delete bb;

    std::cerr << "finished" << std::endl;
}

struct BasicBlockPointer
{
    typedef llvm::BasicBlock element_type;
    typedef BasicBlockPointer this_type;

    boost::shared_ptr<llvm::BasicBlock> m_ptr;

    BasicBlockPointer(element_type * type) :
        m_ptr(type, &BasicBlockDispose)
    {}

    static void install()
    {
        add_pointer_handler<element_type>( &this_type::from_ptr );
    }

    static boost::python::object from_ptr(const void * vptr)
    {
        using namespace boost::python;
        void * fvptr = const_cast<void*>(vptr);
        return object( this_type( reinterpret_cast<element_type*>(fvptr) ) );
    }

    llvm::BasicBlock * get() const
    {
        return m_ptr.get();
    }
};

llvm::BasicBlock * get_pointer(const BasicBlockPointer & ptr)
{
    return ptr.get();
}


namespace boost
{
    namespace python
    {
        template<>
        struct pointee< BasicBlockPointer >
        {
            typedef llvm::BasicBlock type;
        };
        
    }
}

